package com.engine.ch.util;

import com.jcraft.jsch.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class OASFTPUploadUtil {
    private static final Log log = LogFactory.getLog(OASFTPUploadUtil.class);
    private static final String FTP_HOST = "172.30.136.201";
    private static final int FTP_PORT = 8122;
    private static final String FTP_USERNAME = "oa_ftp";
    private static final String FTP_PASSWORD = "8tGV9YHwDvFU";
    private static final String REMOTE_BASE_DIR = "/upload/oa/";

    /**
     * 新的批量上传方法（推荐）
     * @param localFilePaths 本地文件路径列表
     * @param requestId 请求ID，用于创建远程子目录
     */
    public static void uploadFiles(List<String> localFilePaths, String requestId) {
        // 1. 创建并连接客户端
        OASFTPClient ftpClient = new OASFTPClient();
        try {
            ftpClient.connect(FTP_HOST, FTP_PORT, FTP_USERNAME, FTP_PASSWORD);
            String remoteDir = REMOTE_BASE_DIR + requestId + "/";
            ftpClient.ensureRemoteDirectoryExists(remoteDir);

            // 2. 在一个连接内循环上传所有文件
            for (String localFilePath : localFilePaths) {
                File localFile = new File(localFilePath);
                if (!localFile.exists()) {
                    log.error("本地文件不存在，跳过: " + localFilePath);
                    continue;
                }
                ftpClient.uploadFile(localFile, remoteDir);
            }
            log.info("所有文件上传完成。");

        } catch (Exception e) {
            log.error("文件上传过程中发生错误", e);
            throw new RuntimeException("批量文件上传失败", e);
        } finally {
            // 3. 无论成功与否，最终统一关闭连接
            ftpClient.disconnect();
        }
    }

    /**
     * 可复用的 SFTP 客户端内部类
     */
    static class OASFTPClient {
        private Session session;
        private ChannelSftp channelSftp;

        public void connect(String host, int port, String username, String password) throws JSchException {
            JSch jsch = new JSch();
            session = jsch.getSession(username, host, port);
            session.setPassword(password);
            java.util.Properties config = new java.util.Properties();
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);
            session.connect();
            log.info("SFTP会话连接成功");

            Channel channel = session.openChannel("sftp");
            channel.connect();
            channelSftp = (ChannelSftp) channel;
            log.info("SFTP通道建立成功");
        }

        public void ensureRemoteDirectoryExists(String remoteDir) throws SftpException {
            // 简化版目录创建逻辑
            try {
                channelSftp.cd(remoteDir);
            } catch (SftpException e) {
                // 目录不存在，尝试逐级创建
                String[] dirs = remoteDir.split("/");
                StringBuilder path = new StringBuilder();
                for (String dir : dirs) {
                    if (!dir.isEmpty()) {
                        path.append("/").append(dir);
                        try {
                            channelSftp.cd(path.toString());
                        } catch (SftpException e2) {
                            channelSftp.mkdir(path.toString());
                            channelSftp.cd(path.toString());
                            log.debug("创建远程目录: " + path);
                        }
                    }
                }
            }
        }

        public void uploadFile(File localFile, String remoteDir) throws IOException, SftpException {
            String remoteFileName = localFile.getName();
            String remoteFilePath = remoteDir + remoteFileName; // 使用包含子目录的完整路径
            log.info("开始上传文件: " + localFile.getAbsolutePath() + " -> " + remoteFilePath);
            try (FileInputStream fis = new FileInputStream(localFile)) {
                // 使用 put(InputStream, String) 方法，指定远程文件名
                channelSftp.put(fis, remoteFileName);
                log.info("文件上传完成: " + remoteFileName);
            } catch (Exception e) {
                log.error("上传文件失败: " + remoteFileName, e);
                throw e; // 重新抛出异常，由上层处理
            }
        }

        public void disconnect() {
            if (channelSftp != null && channelSftp.isConnected()) {
                channelSftp.disconnect();
                log.debug("SFTP通道已关闭");
            }
            if (session != null && session.isConnected()) {
                session.disconnect();
                log.debug("SFTP会话已关闭");
            }
        }
    }
}